# @Author     ：SEED
# @DateTime   ：2019-08-26  19:49 
# @FileName   ：excel_import.py
from import_export import resources
from import_export.fields import Field
from import_export.widgets import ForeignKeyWidget, ManyToManyWidget, IntegerWidget
from tablib import Dataset
from django.http import JsonResponse
from rest_framework import status
from assets.models import ServerAssets, NetAssets, SpareParts, SpareOut, IDC, Tags
from rest_framework.views import APIView


class ServerResource(resources.ModelResource):
    # 字段转换
    ip = Field(attribute='ip', column_name='服务器IP')
    other_ip = Field(attribute='other_ip', column_name='其他IP')
    management_ip = Field(attribute='management_ip', column_name='管理IP')
    app = Field(attribute='app', column_name='应用')
    app_desc = Field(attribute='app_desc', column_name='应用描述')
    app_env = Field(attribute='app_env', column_name='应用环境')
    auth_type = Field(attribute='auth_type', column_name='认证类型')
    username = Field(attribute='username', column_name='用户名')
    password = Field(attribute='password', column_name='密码')
    # 转化22.0为整数IntegetWidget
    port = Field(attribute='port', column_name='端口', widget=IntegerWidget())
    brand = Field(attribute='brand', column_name='品牌')
    model = Field(attribute='model', column_name='型号')
    os_type = Field(attribute='os_type', column_name='系统类型')
    os_version = Field(attribute='os_version', column_name='系统版本')
    security_domain = Field(attribute='security_domain', column_name='安全域')
    shelves_date = Field(attribute='shelves_date', column_name='上架日期')
    maintenance_date = Field(attribute='maintenance_date', column_name='维保日期')
    type = Field(attribute='type', column_name='服务器类型')
    status = Field(attribute='status', column_name='资产状态')
    sn = Field(attribute='sn', column_name='资产SN')
    device_type = Field(attribute='device_type', column_name='设备类型')
    cabinet = Field(attribute='cabinet', column_name='机柜')
    remarks = Field(attribute='remarks', column_name='备注')
    idc = Field(attribute='idc', column_name='机房', widget=ForeignKeyWidget(IDC, 'name'))
    tags = Field(attribute='tags', column_name='标签', widget=ManyToManyWidget(Tags, ',', 'name'))

    class Meta:
        model = ServerAssets
        report_skipped = True
        skip_unchanged = True  # 导入数据时，跳过未改变的数据
        # 黑名单排除字段
        exclude = ('create_date', 'update_date')
        # 导出排序
        # export_order = ()


class SPResource(resources.ModelResource):
    class Meta:
        model = SpareParts
        report_skipped = True
        skip_unchanged = True  # 导入数据时，跳过未改变的数据


class SOResource(resources.ModelResource):
    class Meta:
        model = SpareOut
        report_skipped = True
        skip_unchanged = True  # 导入数据时，跳过未改变的数据


class NetworkResource(resources.ModelResource):
    management_ip = Field(attribute='management_ip', column_name='管理IP')
    sn = Field(attribute='sn', column_name='资产SN')
    model = Field(attribute='model', column_name='型号')
    brand = Field(attribute='brand', column_name='品牌')
    device_type = Field(attribute='device_type', column_name='设备类型')
    status = Field(attribute='status', column_name='资产状态')
    cabinet = Field(attribute='cabinet', column_name='机柜')
    hostname = Field(attribute='hostname', column_name='主机名')
    app = Field(attribute='app', column_name='应用')
    port = Field(attribute='port', column_name='端口')
    management_segment = Field(attribute='management_segment', column_name='管理网段')
    os_version = Field(attribute='os_version', column_name='系统版本')
    auth_type = Field(attribute='auth_type', column_name='认证类型')
    up_link_port = Field(attribute='up_link_port', column_name='上联端口')
    up_device = Field(attribute='up_device', column_name='上联端口')
    web_url = Field(attribute='web_url', column_name='WEB管理')
    username = Field(attribute='username', column_name='用户名')
    password = Field(attribute='password', column_name='密码')
    remarks = Field(attribute='remarks', column_name='备注')
    shelves_date = Field(attribute='shelves_date', column_name='上架日期')
    maintenance_date = Field(attribute='maintenance_date', column_name='维保日期')

    class Meta:
        model = NetAssets
        report_skipped = True
        skip_unchanged = True  # 导入数据时，跳过未改变的数据
        # 黑名单排除字段
        exclude = ('create_date', 'update_date')
        # 导出排序
        # export_order = ()


class ImportHeader(APIView):
    def get(self, request, *args, **kwargs):
        query = request.query_params['type']
        resource = ''
        if query == 'network':
            resource = NetworkResource()
        elif query == 'server':
            resource = ServerResource()
        header = []
        for i in resource.get_user_visible_fields():
            header.append(i.column_name)


class Import(APIView):
    """
    get : 获取既定表格头
    """

    def get(self, request, *args, **kwargs):
        query = request.query_params['type']
        resource = ''
        if query == 'network':
            resource = NetworkResource()
        elif query == 'server':
            resource = ServerResource()
        header = []
        for i in resource.get_user_visible_fields():
            header.append(i.column_name)
        return JsonResponse({'msg': 'success', 'data': header}, status=status.HTTP_200_OK)

    def post(self, request, *args, **kwargs):
        query = request.query_params['type']
        resource = ''
        if query == 'network':
            resource = NetworkResource()
        elif query == 'server':
            resource = ServerResource()
        dataset = Dataset()
        try:
            new_persons = request.FILES['file']
            imported_data = dataset.load(new_persons.read())
            result = resource.import_data(dataset, dry_run=True,
                                          raise_errors=False, collect_failed_rows=True)  # Test the data import
        except Exception as e:
            return JsonResponse({'error': 'error', 'msg': '导入失败,请检查文件格式或者兼容性,错误信息:' + str(e)},
                                status=status.HTTP_400_BAD_REQUEST)
        if result:
            # if imported_data.headers != result.diff_headers:
            #     print(imported_data.headers)
            #     print(result.diff_headers)
            #     print('表头不一致')
            count = ''
            for k, v in result.totals.items():
                if v != 0:
                    if k == 'update':
                        k = '更新'
                    elif k == 'new':
                        k = '新增'
                    elif k == 'skip':
                        k = '跳过'
                    elif k == 'error':
                        k = '错误'
                    elif k == 'delete':
                        k = '删除'
                    else:
                        k = '无效'
                    count = count + str(k) + ' : ' + str(v) + '条'
            if result.has_errors():
                for error in result.base_errors:
                    return JsonResponse({'error': error.error, 'count': count}, status=status.HTTP_400_BAD_REQUEST)
                error_info = []
                for line, errors in result.row_errors():
                    for error in errors:
                        error_info.append(
                            {'line': str(line), 'key': str(error.error), 'values': str(error.row.values()),
                             'traceback': error.traceback})
                return JsonResponse({'error': error_info, 'count': count, 'msg': '导入错误，请检查以下行'},
                                    status=status.HTTP_400_BAD_REQUEST)
            elif result.has_validation_errors():
                error_info = []
                for row in result.invalid_rows:
                    error_msg = ''
                    key = ''
                    # print(row.error_count)
                    for field_name, error_list in row.field_specific_errors.items():
                        key = field_name
                        for error in error_list:
                            error_msg = error
                            print(error)
                    if row.non_field_specific_errors:
                        for error in row.non_field_specific_errors:
                            print(error)
                            error_msg = error
                    error_info.append({'line': row.number, 'key': key, 'traceback': error_msg})
                return JsonResponse(
                    {'error': error_info, 'count': count, 'msg': '导入错误，请检查以下行'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                resource.import_data(dataset, dry_run=False)  # Actually import now
                return JsonResponse(
                    {'error': None, 'code': 200, 'msg': '导入成功', 'count': count})
